#include "sk_print_bill.h"
#include "pub_var.h"

#include <QSettings>

sk_print_bill::sk_print_bill()
{
    invoice_no = "";

    qrm = new QSqlQuery(pub::db_m);
    qro = new QSqlQuery(pub::db_o);

    QSettings setIni("clin.ini", QSettings::IniFormat);     //配置文件
    QString sk_printer_name = setIni.value("sk/printer").toString();    //收款打印机名称

    //配置打印机
    prt= new QPrinter(QPrinter::HighResolution);
    prt->setPrinterName(sk_printer_name);

    //发票纸张大小设定
    qrm->exec("select p_width,p_height from com_printer_setting "
              "where p_type = '门诊收据' and p_item = '页面'");
    int w = 0, h = 0;

    if(qrm->next())
    {
        w = qrm->value(0).toInt();
        h = qrm->value(1).toInt();
    }
    else
    {
        qDebug()<<"门诊收据打印参数缺失！\n";
    }

    QSizeF sz = QSizeF(w,h);
    QPageSize psz(sz,QPageSize::Millimeter,"mzsj",QPageSize::FuzzyMatch);
    prt->setPageSize(psz);

    QPageLayout pglot = QPageLayout(prt->pageLayout());

    int dotPerInch = prt->physicalDpiX();
    ptScale = double(dotPerInch) / 25.4 ;//转换 以毫米为单位

    prt->setOrientation(QPrinter::Portrait);      // 纵向打印, Landscape 横向打印
    prt->setFullPage(true);
    pnt = new QPainter();

}

sk_print_bill::~sk_print_bill()
{
    delete qrm;
    delete qro;
}

QString sk_print_bill::set_invoice_no(QString invo)
{

    invoice_no = invo;

    mp_page.clear();

    mp_page["发票号"] = invoice_no;

    QString sq ;
    sq = " select reg.name,reg.sex_code,reg.mcard_no,reg.idenno,reg.card_no,"
         " invo.pact_code,invo.pact_name,invo.oper_date,"
         " invo.tot_cost,invo.own_cost,invo.real_cost,invo.oper_code,reg.see_docd "
         " from fin_opr_register reg "
         " left join fin_opb_invoiceinfo invo on invo.clinic_code = reg.clinic_code "
         " where invo.invoice_no = '" + invoice_no + "'";
    qDebug()<<"提取发票基础信息："<<sq<<"\n";
    qro->exec(sq);
    if(!qro->next())
    {
        qDebug()<<"can't find bill " + invo + " number.\n";
        return "can't find bill " + invo + " number.";
    }

    mp_page["姓名"] = qro->value("name").toString();
    mp_page["性别"] = qro->value("sex_code").toString() == "M" ? "男" : "女";
    mp_page["收费类别"] = qro->value("pact_name").toString();
    mp_page["医保卡号"] = qro->value("mcard_no").toString();
    mp_page["门诊号"] = qro->value("card_no").toString();
    mp_page["身份证号"] = qro->value("idenno").toString();
    mp_page["合计"] = qro->value("tot_cost").toString();
    mp_page["real_cost"] = qro->value("real_cost").toString();
    mp_page["own_cost"] = qro->value("own_cost").toString();
    mp_page["大写"] = pub::bigW(qro->value("tot_cost").toDouble());
    mp_page["医院名称"] = pub::hos_name;
    mp_page["操作员"] = qro->value("oper_code").toString();

    //挂号表处方医师绝大多数情况正确。医师开非本人号患者处方时，这个数据会错误。非致命。
    mp_page["处方医师"] = qro->value("see_docd").toString();

    //原始发票票面时间为打印发票的机器系统时间。补打发票时间为数据库保存的时间。不完全一致，误差在秒级。
    QDateTime dt = qro->value("oper_date").toDateTime();
    QString d = dt.toString("yyyy");
    d.append("    ");
    d.append(dt.toString("MM"));
    d.append("    ");
    d.append(dt.toString("dd"));
    d.append("    ");
    d.append(dt.toString("hh:mm:ss"));
    mp_page["日期"] = d;

    sq = " select invo_name,own_cost,dept_name "
         " from fin_opb_invoicedetail "
         " where invoice_no = '" + invo + "' order by invo_code";
    qro->exec(sq);

    qDebug()<<"提取费用分类："<<sq<<"\n";

    int idx = 1;
    while (qro->next())
    {
        mp_page["执行科室"] = qro->value("dept_name").toString();
        mp_page["费别"+QString::number(idx)] = qro->value("invo_name").toString()
                 + " : " + qro->value("own_cost").toString();
    }

    QStringList items = get_items(invo);

    if(items.size() > 10)
    {
        //大于 10 项，不分行
        QString itms = "项目名称 / 数量 / 单价 : \n";

        //QStringList items = getItems(mp["invoice_no"]);

        foreach(QString s, items){
            itms += pub::getStr(s, "^", 1);
            itms += " / ";
            itms += pub::getStr(s, "^", 3);
            itms += " / ";
            itms += pub::getStr(s, "^", 4);
            itms += " ; ";

        }
        mp_page["草药明细"] = itms;  //草药打印不分行
    }
    else
    {
        //小于等于10，逐行打印
        mp_page["项目名头"] = "项目             规格        数量     单价";
        idx = 1;

        foreach(QString s, items)
        {
            mp_page["项目"+QString::number(idx)] = pub::getStr(s, "^", 1);
            mp_page["规格"+QString::number(idx)] = pub::getStr(s, "^", 2);
            mp_page["数量"+QString::number(idx)] = pub::getStr(s, "^", 3);
            mp_page["单价"+QString::number(idx)] = pub::getStr(s, "^", 4);
            idx++;
        }
    }


    if(mp_page["收费类别"] != "现金")
    {
        //医保支付，提取医保相关数据
        sq = " select * "
             " from fin_ipr_siinmaininfo "
             " where invoice_no = '" + invo + "'";
        qDebug()<<"提取医保相关信息："<<sq<<"\n";
        qro->exec(sq);
        qro->next();

        mp_page["卡余额"] = qro->value("individualbalance").toString();
        mp_page["家庭共济"] = qro->value("act_mulaid_pay").toString();

        if(qFuzzyCompare( 0, qro->value("act_mulaid_pay").toDouble()))
        {
            mp_page["账户"] = qro->value("pay_cost").toString();
        }
        else
        {
            mp_page["账户"] = qro->value("pay_cost").toString()
                    + " （家庭共济：" + mp_page["家庭共济"] + "）";
        }

        if(!qFuzzyCompare( 0, qro->value("pub_cost").toDouble()))
        {
            mp_page["统筹"] = qro->value("pub_cost").toString()
                    + " （"
                    + ((qFuzzyCompare( 0, qro->value("hifp_pay").toDouble()))
                       ? "" : "统筹基金支付：" + qro->value("hifp_pay").toString())
                    + ((qFuzzyCompare( 0, qro->value("cvlserv_pay").toDouble()))
                       ? "" : " / 其他支付：" + qro->value("cvlserv_pay").toString())
                    + ((qFuzzyCompare( 0, qro->value("hifes_pay").toDouble()))
                       ? "" : " / 补充险支付：" + qro->value("hifes_pay").toString())
                    + ((qFuzzyCompare( 0, qro->value("hifmi_pay").toDouble()))
                       ? "" : " / 大额支付：" + qro->value("hifmi_pay").toString())
                    + ((qFuzzyCompare( 0, qro->value("hifob_pay").toDouble()))
                       ? "" : " / 大病支付：" + qro->value("hifob_pay").toString())
                    + ((qFuzzyCompare( 0, qro->value("maf_pay").toDouble()))
                       ? "" : " / 医疗救助：" + qro->value("maf_pay").toString())
                    + ((qFuzzyCompare( 0, qro->value("oth_pay").toDouble()))
                       ? "" : " / 其他：" + qro->value("oth_pay").toString())
                    + "）";
        }



    }
    double yf = mp_page["own_cost"].toDouble();  //应付现金
    double sf = mp_page["real_cost"].toDouble();    //实付现金

    if(qFuzzyCompare(yf, sf))
    {
        //无四舍五入
        mp_page["个人"] = mp_page["own_cost"];
    }
    else
    {
        mp_page["个人"] = mp_page["real_cost"] + " (" + mp_page["own_cost"] + ")";
    }

    qDebug()<<"mp_page is : "<<mp_page<<"\n";

    return "";

}

QStringList sk_print_bill::get_items(QString invo)
{
    //检索发票关联的项目明细
    QStringList ret ;

    QString sq;
    sq = "select fee.item_name, fee.specs, fee.qty/fee.pack_qty num, fee.unit_price,"
         " comp.center_item_grade"
         " from fin_opb_feedetail fee"
         " left join fin_com_compare comp on comp.fixmedins_hilist_id = fee.item_code"
         " where fee.invoice_no = '" + invo + "' order by fee.sequence_no";
    qDebug()<<"检索发票关联的项目明细: "<<sq<<"\n";

    qro->exec(sq);
    while (qro->next())
    {
        QString grd = qro->value("center_item_grade").toString();
        QString line;

        if(grd == "01")
        {
            grd = "(甲)";
        }
        else if (grd == "02")
        {
            grd = "(乙)";
        }
        else if (grd == "03")
        {
            grd = "(丙)";
        }
        else
        {
            grd = "";
        }

        //如果字串末尾有多余0，去除至保留两位小数
        //QString::asprintf("%.4f",qro->value(22).toDouble());
        QString prc = QString::asprintf("%.6f",qro->value("unit_price").toDouble());

//        mp["RETAIL_PRICE"] = pub::remove_trailing_zeros(prc);
//        if(qFuzzyCompare(prc.toDouble(), prc.left(prc.length()-1).toDouble()))
//        {
//            prc = prc.left(prc.length()-1);
//        }

//        if(qFuzzyCompare(prc.toDouble(), prc.left(prc.length()-1).toDouble()))
//        {
//            prc = prc.left(prc.length()-1);
//        }

        line += grd;
        line += qro->value("item_name").toString();
        line += "^" + qro->value("specs").toString();
        line += "^" + QString::number(qro->value("num").toInt());
        line += "^" + pub::remove_trailing_zeros(prc);
        ret << line;
    }

    return ret;
}
void sk_print_bill::print_out()
{

    pnt->begin(prt);
    QString item, mode,print_item,font,item_type;
    QFont ft=QFont();
    double top,left,width,height,size;
    int position;
    qrm->prepare("select p_type,p_item,p_top,p_left,p_width,p_height,"
                 "p_font_name,p_font_size,p_position,p_mode,p_print_item,"
                 "p_item_type from com_printer_setting where p_type = '门诊收据'"
                 " and p_item_type in ('item','text')");
    if(!qrm->exec())
    {
        qDebug()<<"读取发票格式数据表失败\n" ;
        return;
    }
    while(qrm->next())
    {

        item = qrm->value("p_item").toString();    //项目名称
        top = qrm->value("p_top").toDouble();
        left = qrm->value("p_left").toDouble();
        width = qrm->value("p_width").toDouble();
        height = qrm->value("p_height").toDouble();
        font = qrm->value("p_font_name").toString();
        size = qrm->value("p_font_size").toDouble();
        position = qrm->value("p_position").toInt();
        mode = qrm->value("p_mode").toString();
        print_item = qrm->value("p_print_item").toString();
        item_type = qrm->value("p_item_type").toString();
        item = mp_page.value(item);  //根据项目名称，在mpPage 取回对应项目值

        if(item.isEmpty()){
            continue;   //空值不打印
        }
        QString outText;    //输入文本
        if(mode == "1"){
            outText = print_item + "：" + item;
        }else if(mode == "0"){
            outText =  item;
        }else  if(mode == "3"){
            outText =  print_item ;
        }

        ft.setPixelSize(int(ptScale * size));

        ft.setFamily(font);
        QFontMetrics fm(ft, prt);
        int pixelsWide = fm.width(outText);

        if( item_type == "item" && pixelsWide > width * ptScale )
        {
            // 打印模式为 item， 且 超过预定格式宽度，缩小字号
            size = size * ( width * ptScale / pixelsWide );//
            ft.setPixelSize(int(ptScale * size));
            ft.setFamily(font);

        }
        if(item_type == "text")
        {
            position = Qt::TextWordWrap | Qt::AlignLeft;// Qt::AlignVCenter |
        }

        pnt->setFont(ft);
        const QRect rect = QRect( left * ptScale, top * ptScale, width * ptScale, height * ptScale);
        QRect boundingRect;
        pnt->drawText(rect, position, outText, &boundingRect);

    }
    pnt->end();
}
